package com.ukefu.webim.util.event;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.commons.lang.StringUtils;
import org.jsoup.Jsoup;

import com.ukefu.core.UKDataContext;
import com.ukefu.util.UKTools;
import com.ukefu.util.ai.AiUtils;
import com.ukefu.webim.service.cache.CacheHelper;
import com.ukefu.webim.service.repository.ChatMessageRepository;
import com.ukefu.webim.util.MessageUtils;
import com.ukefu.webim.util.router.OutMessageRouter;
import com.ukefu.webim.util.server.message.ChatMessage;
import com.ukefu.webim.web.model.AiUser;
import com.ukefu.webim.web.model.MRoundQuestion;
import com.ukefu.webim.web.model.MessageOutContent;

public abstract class AiMRoundsProcesser {
	
	/**
	 * 多轮对话处理
	 * @param aiUser
	 * @param chat
	 * @param mroundsid
	 */
	public abstract ChatMessage process(AiUser aiUser, ChatMessage chat , String mroundsid) ;
	
	
	/**
	 * 多轮对话回复
	 * @param aiUser
	 * @param chat
	 * @param current
	 * @param notMatch
	 */
	public ChatMessage exchange(AiUser aiUser , ChatMessage chat , MRoundQuestion current, MRoundQuestion notMatch , boolean hasChild) {
		ChatMessage retChatMessage = null ;
		boolean end = false ;
		if(aiUser!=null && current != null) {
			if("1".equals(current.getEndbyai()) || hasChild == false) {
				reset(aiUser);
			}else {
				aiUser.setBussid(current.getId());
				aiUser.setDataid(current.getDataid());
				if(current.isInterrupt()) {
					aiUser.setInterrupt(true);
				}
				setLastreplytime(aiUser, current);
			}
			
			aiUser.setErrortimes(0);
			aiUser.setTimeoutnums(0);
			/**
			 * 设置最后一条消息的 ID
			 */
			aiUser.setLastmsgid(chat.getId());
		}else if(aiUser!=null && notMatch!=null){
			setLastreplytime(aiUser, notMatch);
			if(!StringUtils.isBlank(notMatch.getErrorwordup())) {
				String[] errorWords = notMatch.getErrorwordup().split("\\|") ;
				String errorWord = null ;
				if(aiUser.getErrortimes() < errorWords.length) {
					errorWord = errorWords[aiUser.getErrortimes()] ;
				}else {
					errorWord = errorWords[errorWords.length - 1] ;
				}
				if(!StringUtils.isBlank(errorWord)) {
					int errors = 0 ;
					if(!StringUtils.isBlank(notMatch.getErrorepeat()) && notMatch.getErrorepeat().matches("[\\d]{1}")) {
						errors = Integer.parseInt(notMatch.getErrorepeat()) ;
					}
					retChatMessage = syncReplayMessage(notMatch , errorWord , chat , end = (aiUser.getErrortimes()+1 >= errors) , "error" , aiUser);
				}
			}
			aiUser.setErrortimes(aiUser.getErrortimes() + 1);
			aiUser.setLastmsgid(chat.getId());
			if(end == true || hasChild == false) {
				reset(aiUser);
			}
			/**
			 * 重置超时
			 */
			cleanTimeout(aiUser);
			
		}
		if(end == true || hasChild == false) {
			reset(aiUser);
		}
		/**
		 * 更新缓存
		 */
		CacheHelper.getAiUserCacheBean().put(aiUser.getUnikey(), aiUser, UKDataContext.SYSTEM_ORGI);
		return retChatMessage ;
	}
	/**
	 * 
	 * @param aiUser
	 * @param current
	 */
	public void setLastreplytime(AiUser aiUser , MRoundQuestion current) {
		if("1".equals(current.getOvertimetype()) && !StringUtils.isBlank(current.getOvertime()) && current.getOvertime().matches("[\\d]{1,}")) {
			aiUser.setLastreplytime(Integer.parseInt(current.getOvertime())*1000 + System.currentTimeMillis()) ;
		}else {
			aiUser.setLastreplytime(0);
		}
	}
	/**
	 * 
	 * @param aiUser
	 */
	public void reset(AiUser aiUser) {
		aiUser.setBussid(null);
		aiUser.setDataid(null);
		aiUser.setErrortimes(0);
		aiUser.setTimeoutnums(0);
		aiUser.setInterrupt(false);
		aiUser.setLastmsgid(null);
		
		aiUser.setLastreplytime(0);
	}
	
	/**
	 * 
	 * @param aiUser
	 */
	public void cleanTimeout(AiUser aiUser) {
		aiUser.setLastreplytime(0);
	}

	/**
	 * 多轮对话回复
	 * @param aiUser
	 * @param chat
	 * @param current
	 * @param notMatch
	 */
	public ChatMessage overtime(AiUser aiUser , MRoundQuestion current , ChatMessage chat) {
		ChatMessage retChatMessage = null ;
		boolean end = false ;
		if(aiUser!=null && current != null) {
			aiUser.setLastreplytime(0);
			if(!StringUtils.isBlank(current.getOvertimeword())) {
				String[] overtimeWords = current.getOvertimeword().split("\\|") ;
				String overtimeWord = null ;
				if(aiUser.getErrortimes() < overtimeWords.length) {
					overtimeWord = overtimeWords[aiUser.getErrortimes()] ;
				}else {
					overtimeWord = overtimeWords[overtimeWords.length - 1] ;
				}
				if(!StringUtils.isBlank(overtimeWord)) {
					int overtimes = 0 ;
					if(!StringUtils.isBlank(current.getOvertimerepeat()) && current.getOvertimerepeat().matches("[\\d]{1}")) {
						overtimes = Integer.parseInt(current.getOvertimerepeat()) ;
					}
					replayMessage(current , overtimeWord , chat ,end = (aiUser.getTimeoutnums() + 1 >= overtimes) , "timeout" , 200 , aiUser);
				}
			}
			aiUser.setTimeoutnums(aiUser.getTimeoutnums() + 1);
			
			if(end) {
				reset(aiUser);
			}
			CacheHelper.getAiUserCacheBean().put(aiUser.getUnikey(), aiUser, UKDataContext.SYSTEM_ORGI);
		}
		return retChatMessage ;
	}
	/**
	 * 回复消息
	 * @param mrq
	 */
	protected void replayMessage(final MRoundQuestion mrq ,final String content , final ChatMessage message , final boolean end ,final String endcase , int delay , final AiUser aiUser) {
		new Timer().schedule(new TimerTask(){  
			public void run(){  
				ChatMessage retChatMessage = syncReplayMessage(mrq, content, message , end , endcase , aiUser) ;
				UKDataContext.getContext().getBean(ChatMessageRepository.class).save(message) ;
				
				MessageOutContent outMessage = MessageUtils.createAiMessage(retChatMessage , retChatMessage.getAppid(), retChatMessage.getChannel(), UKDataContext.CallTypeEnum.OUT.toString() , UKDataContext.AiItemType.AIREPLY.toString() , !StringUtils.isBlank(retChatMessage.getMsgtype()) ? retChatMessage.getMsgtype() : UKDataContext.MediaTypeEnum.TEXT.toString(), aiUser.getUserid()) ;
				
				if(!StringUtils.isBlank(retChatMessage.getUserid()) && UKDataContext.MessageTypeEnum.MESSAGE.toString().equals(retChatMessage.getType())){
		    		if(!StringUtils.isBlank(retChatMessage.getTouser()) && (message.isDebug() || retChatMessage.isSkip() == false)){
			    		
		    			OutMessageRouter router = null ; 
			    		router  = (OutMessageRouter) UKDataContext.getContext().getBean(retChatMessage.getChannel()) ;
			    		if(router!=null){
			    			router.handler(retChatMessage.getTouser(), UKDataContext.MessageTypeEnum.MESSAGE.toString(), retChatMessage.getAppid(), outMessage);
			    		}
			    	}
		    	}
			}
		},delay); 
	}
	
	/**
	 * 回复消息
	 * @param mrq
	 */
	protected ChatMessage syncReplayMessage(final MRoundQuestion mrq ,final String content , final ChatMessage message , boolean end , String endcase , AiUser aiUser) {
		ChatMessage retChatMessage = new ChatMessage();
		retChatMessage.setMessage(content);
		retChatMessage.setUsername("小E");
		
		
		if(StringUtils.isBlank(Jsoup.parse(retChatMessage.getMessage()).text().replace("[\\pP\\p{Punct}]", " "))) {
			retChatMessage.setSkip(true);
			
			retChatMessage.setMessage("<i style='color:red;'>多轮对话配置内容为空</i>");
		}
		
		retChatMessage.setMround(true);
		retChatMessage.setQuesid(mrq.getId());
		retChatMessage.setDataid(mrq.getDataid());
		retChatMessage.setMtype(mrq.getMtype());
		retChatMessage.setCalltype(UKDataContext.CallTypeEnum.OUT.toString());
		
		if(mrq.isStaticagent()) {
			retChatMessage.setStaticagent(true);
		}
		
		if(mrq!= null && mrq.isBussop() && !StringUtils.isBlank(mrq.getBusslist())) {
			AiUtils.processAiUserNames(message.getMessage(), mrq.getBusslist(), mrq.isBussop(), aiUser,mrq.getBussclist() , null);
		}
		
		if(message!=null) {
			retChatMessage.setAppid(message.getAppid());
			retChatMessage.setUserid(aiUser.getUnikey());
			retChatMessage.setCreater(aiUser.getUserid());
			retChatMessage.setChannel(message.getChannel());
			retChatMessage.setType(message.getType());
			retChatMessage.setContextid(message.getContextid());
			retChatMessage.setOrgi(message.getOrgi());
			
			retChatMessage.setTouser(aiUser.getUnikey());
			retChatMessage.setUsession(message.getUsession());
			retChatMessage.setAgentserviceid(message.getAgentserviceid());
			
			if(message.isDebug()) {
				StringBuffer strb = new StringBuffer();
				strb.append("多轮对话匹配，名称："+mrq.getName()+" \r\n匹配规则："+mrq.getTitle() + "\r\ntype : "+mrq.getMtype() + "\r\nid:" + mrq.getDataid() + "\r\n延迟：" + (!StringUtils.isBlank(mrq.getDelay()) ? mrq.getDelay() : "0") + "秒\r\n") ;
				if(aiUser.getNames().size()>0) {
					strb.append("采集的业务关键词：").append(UKTools.toJson(aiUser.getNames().get("bustype"))).append("\r\n") ;
				}
				if(end) {
					switch(endcase) {
						case "ai" : strb.append("到达节点后结束") ;break;
						case "nochild" : strb.append("无下级节点结束") ;break;
						case "timeout" : strb.append("超时达到最大次数结束") ;break;
						case "error" : strb.append("回答错误达到最大次数结束") ;break;
					}
				}else {
					strb.append("未结束") ;
				}
				retChatMessage.setExpmsg(strb.toString());
			}
		}
		return retChatMessage ;
	}
	
	/**
	 * 检测是否结束
	 * @param mRoundsQuestionList
	 * @param current
	 * @return
	 */
	protected boolean hasChilde(List<MRoundQuestion> mRoundsQuestionList , MRoundQuestion current) {
		boolean sub = false ;
		if(mRoundsQuestionList!=null && current!=null) {
			for(MRoundQuestion mRoundsQues : mRoundsQuestionList) {
				if(mRoundsQues.getParentid()!=null && mRoundsQues.getParentid().equals(current.getId())) {
					sub = true ; break ;
				}
			}
		}
		return sub ;
	}
	
	/**
	 * 检测是否结束
	 * @param mRoundsQuestionList
	 * @param current
	 * @return
	 */
	protected boolean hasChildeNotRoot(List<MRoundQuestion> mRoundsQuestionList , MRoundQuestion current) {
		boolean sub = false ;
		if(mRoundsQuestionList!=null && current!=null) {
			for(MRoundQuestion mRoundsQues : mRoundsQuestionList) {
				if(mRoundsQues.getParentid()!=null && mRoundsQues.getParentid().equals(current.getId()) && !current.getId().equals(current.getParentid())) {
					sub = true ; break ;
				}
			}
		}
		return sub ;
	}
}
